﻿/**
 * 8051虚拟机具体实现
 *
 * 创建时间：2022年5月21日
 * 作者：李述铜
 * 联系邮箱: 527676163@qq.com
 */
#include <string.h>
#include <stdio.h>
#include "simu8051.h"

// 8051 simulator
static simu8051_t simu;

uint8_t simu8051_read (mem_type_t type, uint16_t addr) {
    switch (type) {
    case MEM_TYPE_IRAM:
        return 0;
    case MEM_TYPE_XRAM:
        return 0;
    case MEM_TYPE_CODE:
        return 0;
    case MEM_TYPE_SFR:
        return 0;
    case MEM_TYPE_BIT:
        return 0;
    default:
        return 0;
    }
}

void simu8051_write (mem_type_t type, uint16_t addr, uint8_t data) {
    switch (type) {
    case MEM_TYPE_IRAM:
        break;
    case MEM_TYPE_XRAM:
        break;
    case MEM_TYPE_CODE:
        break;
    case MEM_TYPE_SFR:
        break;
    case MEM_TYPE_BIT:
        break;
    }
}

void simu8051_reset(void) {
    simu.pc = 0x0;
}

/**
 * initialize 8051 simulator
 */
void simu8051_init(void) {
    simu.mem.code = (uint8_t *)0;
    memset(simu.mem.xram, 0, MEM_XRAM_SIZE);
    memset(simu.mem.iram, 0, MEM_IRAM_SIZE);
    memset(simu.mem.sfr, 0, MEM_SFR_SIZE);

    simu8051_reset();
}

uint16_t simu8051_pc(void) {
    return simu.pc;
}

void simu8051_fetch_instr(instr_t * instr) {
    instr->opcode = simu.mem.code[simu.pc];
    instr->op0 = simu.mem.code[simu.pc + 1];
    instr->op1 = simu.mem.code[simu.pc + 2];
}

void simu8051_exec (instr_t * instr) {
    switch (instr->opcode) {
        case 0x00: {
            printf("%d: %s\n", simu.pc, "nop");
            simu.pc += 1;
            break;
        }
        case 0x80: {
            printf("%d: %s\n", simu.pc, "sjmp");
            simu.pc += 2 + (int8_t)instr->op0;
            break;
        }
    }
}

void simu8051_load(uint8_t * code) {
    simu.mem.code = code;
}
